-
Notifications
You must be signed in to change notification settings - Fork 888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use managed HTTP stack #1618
Use managed HTTP stack #1618
Conversation
We could create a nuget package for this, so that @tmat can try it out. eg, |
May I ask this is about server side smart transport? |
No, libgit2 has no support for that. This is intended to allow us to use the .NET HTTP stack instead of using libgit2's networking stack. That means that we don't need to take a dependency on openssl or curl on non-Windows platforms, which has become incredibly problematic. |
Note to self: the certificate validation callback mechanism in libgit2 assumes that there is always a certificate callback and so things get quite crashy when there isn't. We'll need to support this when it's unset. |
e06837a
to
3101db8
Compare
924f342
to
8e5c177
Compare
420908c
to
ea06a88
Compare
LibGit2Sharp/LibGit2Sharp.csproj
Outdated
@@ -1,7 +1,7 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
|
|||
<PropertyGroup> | |||
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks> | |||
<TargetFrameworks>netcoreapp2.0;net472</TargetFrameworks> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it's ok to change the test projects to net472 if you really want to, these can't be changed like this. They need to stay as netstandard2.0;net461
.
We probably shouldn't change the test projects either, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 4.6.1 and not 4.7.2? (https://twitter.com/terrajobst/status/1031999730320986112)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, and that's why I'm saying we need a net461
target. .NET Standard 2.0 works with net461
even if its "broken", so you need to provide a net461
target to ensure that gets chosen over the netstandard2.0
target.
See https://docs.microsoft.com/en-us/dotnet/standard/library-guidance/cross-platform-targeting for more on that.
Libraries shouldn't target netcoreapp2.0
, so that leads us back to netstandard2.0;net461
being the correct targets here.
var httpClientHandler = CreateClientHandler(); | ||
httpClientHandler.Credentials = credentials; | ||
|
||
using (var httpClient = new HttpClient(httpClientHandler)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you'll be changing to use the httpClient
field instead? Even though the HttpClient
class implements IDisposable
, you're not supposed to create one and dispose it per request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unclear: the credentials belong to the handler and it appears that credentials can't be changed after a request has been issued. It's not clear if using a CredentialCache
will be sufficient to satisfy that and support default credentials both. Possible that I could implement my own ICredentials
mechanism as a last resort.
request.Content.Headers.Add("Content-Type", ContentType); | ||
} | ||
|
||
var response = httpClient.SendAsync(request).Result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocking on an async call like that isn't a great idea, but I guess this will have been called from libgit2? When that happens, what thread will it be on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be more correct to do httpClient.SendAsync(request).ConfigureAwait(false).GetAwaiter().GetResult()
? Accessing .Result
directly in a library can cause deadlocks, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.GetAwaiter().GetResult()
causes the same deadlocks as .Result
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(also, the comment you're responding to is a year and a half old and marked as "Outdated")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ouch, sorry.
2513a40
to
09dce90
Compare
Okay, with 09dce90 this is mostly working (occasional errors with "early EOF" that I don't yet understand). Moving the core library back to |
@ethomson I was going to try and push up a new preview release, but I'm getting some errors on Azure Pipelines. It's asking me to login and then saying I don't have permission, and getting 500 errors on other links. Any ideas? |
🤔 Interesting question. I can view the artifacts - is it possible that this is a thing that you need to be logged in to Azure Pipelines to download? I didn't remember that being the case, but I've also lost all the familiarity with Azure Pipelines that I once had. I can invite you to the project though, what email address should I use? (Feel free to email it to me direct if that's easier.) |
I feel like I used to be able to access everything in Azure Pipelines, so maybe something changed?
I'll send you a DM in the libgit2 slack. |
These changes have been published in 0.27.0-preview-0096. Give it a try and let me know if anything explodes. |
With pleasure! |
@bording A great many of my tests are failing with this exception. Is it expected that
|
I'm not aware of anything that this PR would have done that would have any impact on that. |
There shouldn't be a limit on the number of times that you can call But I don't understand what that has to do with:
|
I don't think this PR is related either. Must be some other change. I'll open an issue. |
Next issue: the tests pass on Windows but fail on Linux. This is because I have a linux-arm linux-arm64 linux-musl-x64 linux-x64 osx win-x64 win-x86 That's probably exactly what you were expecting, and presumably made possible because of the drop of the native HTTPS stack. |
Happily, ripping the |
Great! That was what I was hoping would work. By only having the base RIDs, all distros should just be able to use those without any special mapping. |
Does this mean it should work on Linux on mono as well? |
The story is much improved there as well, though not perfect. The I think I can add more |
For nb.gv, I think what we have is good enough. St least until users complain about arm or musl not working. |
The main thing that actually needs to be validated is whether or not the set of linux binaries in the package actually work on all the various distros that .NET Core works on. I'm reasonable sure that they will, but I haven't had a way to test that myself. |
NB.GV uses Azure Pipelines to test a variety of linux distros. Basically any that we do something to make work, we add a regression test for. You can see it here by expanding "functional testing" here: https://dev.azure.com/andrewarnott/OSS/_build/results?buildId=3979&view=results |
Yeah, adding some tests with different distros via docker images would help, but there are some distros that don't have images available (RHEL, SLES). It's something I'll have to look into eventually. |
Ya, Pop!_OS doesn't seem to have a docker image anywhere, and that has come up a few times as one that folks want NB.GV to work in. I had to create a VM and test manually. |
Integrate new implementations from libgit2/libgit2sharp#1618 With the previous version, in deployments on Docker found the 'load from git' function in the Elm Editor did not work. The backend returned this error with the HTTP response: ``` Exception in volatile host: System.AggregateException: One or more errors occurred. (The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception.) ---> System.TypeInitializationException: The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception. ---> System.DllNotFoundException: Unable to load shared library 'git2-106a5f2' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libgit2-106a5f2: cannot open shared object file: No such file or directory at LibGit2Sharp.Core.NativeMethods.git_libgit2_init() at LibGit2Sharp.Core.NativeMethods.InitializeNativeLibrary() at LibGit2Sharp.Core.NativeMethods..cctor() --- End of inner exception stack trace --- at LibGit2Sharp.Core.NativeMethods.git_clone(git_repository*& repo, String origin_url, FilePath workdir_path, GitCloneOptions& opts) at LibGit2Sharp.Core.Proxy.git_clone(String url, String workdir, GitCloneOptions& opts) at LibGit2Sharp.Repository.Clone(String sourceUrl, String workdirPath, CloneOptions options) at Kalmit.LoadFromGithub.LoadFromUrl(String sourceUrl) in /app/PersistentProcess/PersistentProcess.Common/LoadFromGithub.cs:line 109 at Kalmit.LoadFromPath.LoadTreeFromPath(String path) in /app/PersistentProcess/PersistentProcess.Common/LoadFromPath.cs:line 11 [...] ``` See the discussion of the problem at libgit2/libgit2sharp#1798 Another workaround found in the discussion was switching to the bionic flavor of the .net docker image.
Integrate new implementations from libgit2/libgit2sharp#1618 With the previous version, in deployments on Docker found the 'load from git' function in the Elm Editor did not work. The backend returned this error with the HTTP response: ``` Exception in volatile host: System.AggregateException: One or more errors occurred. (The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception.) ---> System.TypeInitializationException: The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception. ---> System.DllNotFoundException: Unable to load shared library 'git2-106a5f2' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libgit2-106a5f2: cannot open shared object file: No such file or directory at LibGit2Sharp.Core.NativeMethods.git_libgit2_init() at LibGit2Sharp.Core.NativeMethods.InitializeNativeLibrary() at LibGit2Sharp.Core.NativeMethods..cctor() --- End of inner exception stack trace --- at LibGit2Sharp.Core.NativeMethods.git_clone(git_repository*& repo, String origin_url, FilePath workdir_path, GitCloneOptions& opts) at LibGit2Sharp.Core.Proxy.git_clone(String url, String workdir, GitCloneOptions& opts) at LibGit2Sharp.Repository.Clone(String sourceUrl, String workdirPath, CloneOptions options) at Kalmit.LoadFromGithub.LoadFromUrl(String sourceUrl) in /app/PersistentProcess/PersistentProcess.Common/LoadFromGithub.cs:line 109 at Kalmit.LoadFromPath.LoadTreeFromPath(String path) in /app/PersistentProcess/PersistentProcess.Common/LoadFromPath.cs:line 11 [...] ``` See the discussion of the problem at libgit2/libgit2sharp#1798 and libgit2/libgit2sharp#1747 Another workaround found in the discussion was switching to the bionic flavor of the .net docker image.
In an attempt to reduce our native dependencies, we can use the managed HTTP stack for connecting to HTTP remotes. This is somewhat working but lacking a number of pieces of functionality:
ProxiesCertificate validation callbacksHowever, for users who do not do any networking, this may be worth evaluation.